﻿using BBCore.Application.Admins;
using BBCore.Application.Interface;
using BBCore.Core.Models.BaseModels;
using BBCore.Core.Models.EnumTypes;
using BBCore.Core.Models.Samples;
using BBCore.Infrastructure.Helps;
using BootstrapBlazor.Components;
using FreeSql.Aop;
using Magicodes.ExporterAndImporter.Core.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using System.Diagnostics.CodeAnalysis;

namespace BBCore.Server.PublicComponentBase
{
    /// <summary>
    /// 模板代码生成器基类
    /// </summary>
    public class Template_ComponentBase : ComponentBase
    {
        [NotNull]
        [Inject]
        protected IFreeSql? freeSql { get; set; }

        [NotNull]
        [Inject]
        protected IGetLoginUserNameService? GetLoginUserNameService { get; set; }

        [NotNull]
        [Inject]
        protected IAdminService? AdminService { get; set; }
        [NotNull]
        [Inject]
        protected AuthenticationStateProvider? authStateProvider { get; set; }

        [NotNull]
        [Inject]
        protected NavigationManager? NavigationManager { get; set; }
        [NotNull]
        [Inject]
        protected IExporterAndImporterService? IExporterAndImporterService { get; set; }
        [NotNull]
        [Inject]
        protected DownloadService? DownloadService { get; set; }
        [Inject]
        [NotNull]
        protected ToastService? ToastService { get; set; }
        [Inject]
        [NotNull]
        protected SwalService? SwalService { get; set; }
        [NotNull]
        protected string? Username { get; set; }
        protected override async Task OnInitializedAsync()
        {
            // 先获取用户名
            Username = await GetLoginUserNameAsync(authStateProvider);

            // 配置审计拦截器
            ConfigureFreeSqlAuditInterceptor();

            await base.OnInitializedAsync(); // 调用原始基类逻辑
        }
        /// <summary>
        /// 抽象获取用户名的方法（子类可重写）
        /// </summary>
        /// <param name="authProvider">AuthenticationStateProvider</param>
        /// <returns></returns>
        protected virtual async Task<string> GetLoginUserNameAsync(AuthenticationStateProvider authProvider)
        {
            return await GetLoginUserNameService.GetLoginUserNameAsync(authProvider);
        }
        /// <summary>
        /// 配置 FreeSql 审计值拦截器
        /// </summary>
        protected void ConfigureFreeSqlAuditInterceptor()
        {
            freeSql.Aop.AuditValue += (s, e) =>
            {
                var currentUser = Username;
                var now = DateTime.Now;
                if (e.Object is BaseModel modelBase)//检查类型，判断当前操作的实体是否需要审计
                {
                    if (e.AuditValueType == AuditValueType.Insert)
                    {
                        if (e.Property.Name == nameof(BaseModel.CREATION_DATE))
                            e.Value = now;
                        //扩展:如果需要更复杂的审计（如记录操作日志），可在基类中添加额外方法                    
                        if (e.Property.Name == nameof(BaseModel.CREATED_BY))
                            e.Value = currentUser;
                    }
                    else if (e.AuditValueType == AuditValueType.Update)
                    {
                        if (e.Property.Name == nameof(BaseModel.LAST_UPDATED_BY))
                            e.Value = currentUser;
                        if (e.Property.Name == nameof(BaseModel.LAST_UPDATED_DATE))
                            e.Value = now;
                    }

                }
            };
        }

        /// <summary>
        /// 按钮权限验证
        /// </summary>
        /// <param name="operate">操作的动作ButtonPermissionTypeEnum</param>
        /// <returns></returns>
        protected bool AuthorizeButton(ButtonPermissionTypeEnum operate)
        {
            var url = "/" + NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
            if (Username == BBCore_Constant.adminName)
            {
                return true;
            }
            else
            {
                return AdminService.AuthorizingBlock(Username, url, operate.ToString());
            }
        }
        /// <summary>
        /// 下载模板文件
        /// </summary>
        /// <param name="filepath">例如await IExporterAndImporterService.TemplateDownloadAsync<T>();获取得到文件路径</param>
        /// <returns></returns>
        protected async Task DownloadFromFileAsync(string filepath)
        {
            string fileName = Path.GetFileName(filepath);
            await DownloadService.DownloadFromFileAsync(fileName, filepath);
        }
        /// <summary>
        /// 导入前检查后缀格式和文件大小
        /// </summary>
        /// <param name="uploadFile">上传的文件</param>
        /// <returns></returns>
        protected async Task onBeforeCheck(UploadFile uploadFile)
        {
            if (uploadFile.GetExtension() != ".xlsx")
            {
                await SwalService.Show(new SwalOption()
                {
                    Content = "导入出错了,只支持上传.xlsx格式的excel文件",
                    Category = SwalCategory.Error
                });
                return;
            }
            if (uploadFile.Size > 10 * 1024 * 1024) // 10MB 转换为字节
            {
                await SwalService.Show(new SwalOption()
                {
                    Content = "导入出错了,文件大小不得超过 10MB",
                    Category = SwalCategory.Error
                });
                return;
            }
        }

        /// <summary>
        /// 通用数据导入方法
        /// </summary>
        /// <typeparam name="TEntity">导入实体类型</typeparam>
        /// <param name="uploadFile">上传文件</param>
        /// <param name="insertAction">数据插入操作委托</param>
        protected async Task Data_Import_Common<TEntity>(
            UploadFile uploadFile,
            Func<IEnumerable<TEntity>, Task<int>> insertAction)
            where TEntity : class, new()
        {
            await onBeforeCheck(uploadFile);

            using MemoryStream stream = new MemoryStream();
            var items = await IExporterAndImporterService.importResultAsync<TEntity>(uploadFile, stream);

            if (items.RowErrors?.Count > 0)
            {
                await HandleImportValidateError<TEntity>(items.RowErrors);
                return;
            }

            await HandleImportResultAsync(items.Data, insertAction, "导入");
        }

        /// <summary>
        /// 单表导入方法
        /// </summary>
        /// <typeparam name="T">Tmodel</typeparam>
        /// <param name="uploadFile">上传的文件</param>
        /// <returns></returns>
        protected Task Data_Import<T>(UploadFile uploadFile) where T : class, new()
        {
            return Data_Import_Common<T>(uploadFile, async data =>
            {
                var lst = data.ToList();
                return await freeSql.Insert(lst).ExecuteAffrowsAsync();
            });
        }
        /// <summary>
        /// 返回主表+id的字符串,组成记录锁的唯一性
        /// </summary>
        /// <typeparam name="TMaster">主表</typeparam>
        /// <typeparam name="TDetail">从表</typeparam>
        /// <typeparam name="TKey">类型,例如int,string</typeparam>
        /// <param name="entity">主表</param>
        /// <returns>例如:HYJ_Master_Table_8</returns>
        protected string GetLockKey<TMaster, TDetail, TKey>(TMaster entity)
             where TMaster : class, IMasterTable<TKey, TDetail>
             where TDetail : class, IDetailTable<TKey>
             => $"{typeof(TMaster).Name}_{entity.HEAD_ID}";
        protected string GetLockKey<TMaster, TDetail, TKey>(int headId) => $"{typeof(TMaster).Name}_{headId}";

        /// <summary>
        /// 主从表导入方法
        /// </summary>
        /// <typeparam name="TMaster">主表</typeparam>
        /// <typeparam name="TDetail">从表</typeparam>
        /// <typeparam name="TKey">类型,例如int,guid</typeparam>
        /// <param name="uploadFile">上传的文件</param>
        /// <param name="master">主表</param>
        /// <returns></returns>
        protected Task Data_Import<TMaster, TDetail, TKey>(UploadFile uploadFile, TMaster master)
            where TMaster : class, IMasterTable<TKey, TDetail>, new()
            where TDetail : class, IDetailTable<TKey>, new()
        {
            return Data_Import_Common<TDetail>(uploadFile, async data =>
            {
                var details = data.ToList();
                if (details?.Count > 0)
                {
                    details.ForEach(detail =>
                    {
                        // 通过接口访问主表ID
                        detail.BODY_ID = master.HEAD_ID;
                    });
                }
                return await freeSql.Insert(details).ExecuteAffrowsAsync();
            });
        }


        /// <summary>
        /// 通用的导入结果处理方法（模板方法）
        /// </summary>
        /// <typeparam name="T">TModel</typeparam>
        /// <param name="data">导入的数据</param>
        /// <param name="dataOperation">接收处理逻辑的委托    </param>
        /// <param name="operationName">可自定义的操作名称,例如插入,导入</param>
        /// <returns></returns>
        private async Task HandleImportResultAsync<T>(IEnumerable<T> data, Func<IEnumerable<T>, Task<int>> dataOperation, string operationName = "操作") where T : class
        {
            try
            {
                int affectedRows = await dataOperation(data);
                await ShowSwalMessageAsync($"成功{operationName} {affectedRows} 条记录", SwalCategory.Success);
            }
            catch (Exception ex)
            {
                await ShowSwalMessageAsync($"{operationName}出错了: {ex.Message}", SwalCategory.Error);
            }
        }



        /// <summary>
        /// 导入验证出错信息
        /// </summary>
        /// <typeparam name="T">Tmodel</typeparam>
        /// <param name="dataRowErrors">出错信息</param>
        /// <returns></returns>
        private async Task HandleImportValidateError<T>(IList<DataRowErrorInfo> dataRowErrors) where T : class, new()
        {
            var filepath = await IExporterAndImporterService.TemplateErrorInfoAsync<T>(dataRowErrors);
            string fileName = Path.GetFileName(filepath);
            await DownloadService.DownloadFromFileAsync(fileName, filepath);
            await ShowSwalMessageAsync("导入验证出错,请查看具体的出错信息", SwalCategory.Error);
        }
        /// <summary>
        /// SweetAlert 弹窗组件,ShowMessage
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="category">消息类型</param>
        /// <returns></returns>
        public async Task ShowSwalMessageAsync(string content, SwalCategory category)
        {
            await SwalService.Show(new SwalOption()
            {
                Content = content,
                Category = category
            });
        }
        /// <summary>
        /// Toast 弹窗
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="category">消息类型</param>
        /// <returns></returns>
        public async Task ShowToastMessageAsync(string content, ToastCategory category)
        {
            await ToastService.Show(new ToastOption()
            {
                Content = content,
                Category = category
            });
        }
    }
}
